package com.ruoyi.web.controller.system;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.business.service.IWsdSchoolsService;
import com.ruoyi.business.service.IWsdStudentsService;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.dto.wxUserDataDTO;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.WsdSchools;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.vo.studentInformationVO;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.zip.DeflaterOutputStream;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@RestController
@Slf4j
public class SysLoginController {
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IWsdStudentsService wsdStudentsService;

    @Autowired
    private IWsdSchoolsService wsdSchoolsService;

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody)
    {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 根据家长信息获取学生信息
     *
     * @return 用户信息
     */
    @GetMapping("student_information")
    public AjaxResult studentInformation() {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if ("11".equals( user.getUserType() )) {
            Long schoolId = user.getSchoolId();
            String phonenumber = user.getPhonenumber();
            Long studentId = user.getStudentId();
//        if (user.getStudentId()==null){
//            return AjaxResult.warn("该账号下没有学生信息");
//        }
            //获得学生的信息
            List<studentInformationVO> studentInformationVO = wsdStudentsService.studentInformation( schoolId, studentId );
            if (ObjectUtils.isEmpty( studentInformationVO )) {
                return AjaxResult.warn( "该账号下没有学生信息" );
            }
            AjaxResult ajax = AjaxResult.success();
            for (studentInformationVO informationVO : studentInformationVO) {
                informationVO.setUser( user );
                if (informationVO.getStudentsSex() == 0) {
                    informationVO.setStudentSexName( "男" );
                }else {
                    informationVO.setStudentSexName( "女" );
                }
            }
            ajax.put( "studentInformationVO", studentInformationVO );
            return ajax;
        }else {
            AjaxResult ajax = AjaxResult.success();
            List<studentInformationVO> studentInformationVOList = new ArrayList<>();
            studentInformationVO studentInformationVO = new studentInformationVO();
            studentInformationVO.setNickName( user.getNickName() );
            studentInformationVO.setStudentsName( user.getNickName() );
            WsdSchools wsdSchools = wsdSchoolsService.selectWsdSchoolsById(user.getSchoolId());
            studentInformationVO.setSchoolName( wsdSchools.getName() );
            studentInformationVO.setClassesName( "班级名称" );
            studentInformationVO.setPhonenumber( user.getPhonenumber() );
            studentInformationVO.setUser( user );
            studentInformationVOList.add( studentInformationVO );
            ajax.put( "studentInformationVO", studentInformationVOList );
            return ajax;
        }
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters() {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(menuService.buildMenus(menus));
    }

    /**
     * 验证码的登录
     * @param loginBody
     * @return
     */
    @PostMapping("/appCodeLogin")
    public AjaxResult appCodeLogin(@RequestBody LoginBody loginBody) {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.appCodeLogin(loginBody.getPhone(), loginBody.getCode(), loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /**
     * 发送手机号登录验证码
     * @param
     * @param phone
     * @return
     */
    @GetMapping("/appCaptcha")
    public AjaxResult getAppCode(String phone) {
        //创建一个返回对象
        AjaxResult ajax = AjaxResult.success();
        // 保存验证码信息
        String uuid = IdUtils.simpleUUID(); //生成一个uuid
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
        // 生成四位数验证码
        Random randObj = new Random();
        String code = Integer.toString(100000 + randObj.nextInt(900000));
        // 通过阿里云短信发送短信
        String templateCode = "SMS_465413763";
        //AliyunSmsUtils.sendSms(phone,templateCode,code);
        System.out.println(code);
        //把验证码答应存入缓存，3分钟的时间
        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        //把信息封装返回
         ajax.put("uuid", uuid);
         return ajax;
    }

    /**
     * 获取密钥
     * @param code
     * @return
     * @throws WxErrorException
     * @throws JsonProcessingException
     */
    @PostMapping("/wechatSession")
    public AjaxResult wechatSession(@RequestParam String code) throws WxErrorException, JsonProcessingException {
        //获取openId、unionid、session_key
        WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
        // 保存sessionKey和openid
        String uuid = UUID.randomUUID().toString();; //生成一个uuid
        //存入缓存，3分钟的时间
        // 将对象转换为 JSON 字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(sessionInfo);
        redisTemplate.opsForValue().set(Constants.RedisKey + uuid, json,Constants.STATUS, TimeUnit.MINUTES);
        System.out.println(json);
        return AjaxResult.success(uuid);
    }

    /**
     * 微信小程序手机号登录
     * @param wxUserDataDto
     * @return
     */
    @PostMapping(value = "/wechatLogin")
    public AjaxResult wechatLogin(@RequestBody wxUserDataDTO wxUserDataDto) {
        Map<String, Object> userInfoMap = new HashMap<>();
        String json = redisTemplate.opsForValue().get(Constants.RedisKey + wxUserDataDto.getUuid());
        JSONObject jsonObject = JSON.parseObject(json);
        String sessionKey = (String) jsonObject.get("sessionKey");
        String openid = (String) jsonObject.get("openid");
        WxMaPhoneNumberInfo phoneInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, wxUserDataDto.getEncryptedData(),wxUserDataDto.getIv());
        //查询家长是否有这个用户
        String phone = phoneInfo.getPhoneNumber();
        SysUser sysUser = userService.selectByPhone(phone);
        if (ObjectUtils.isEmpty(sysUser)){
            return AjaxResult.error("你的手机号在系统还没有录入,请联系管理员");
        }else {
            //组装token信息
            LoginUser loginUser = new LoginUser();
            loginUser.setOpenId(openid);
            //如果有的话设置
            loginUser.setUser(sysUser);
            loginUser.setUserId(sysUser.getUserId());
            // 生成token
            String token = tokenService.createToken(loginUser);
            userInfoMap.put(Constants.TOKEN,token);
        }
        log.info("token" + userInfoMap);
        return AjaxResult.success(userInfoMap);
    }
}
